12. Exercise: Creating a Room Database

L6 19 Room Database Code SC

Now it’s your turn to complete this exercise yourself.

In this step, you'll write the code to create a Room database for your app.

  1. In SleepDatabase.kt, create an abstract class that extends RoomDatabase.

    Annotate the class with @Database and supply the SleepNight for entities, version as 1, and exportSchema set to false.

 @Database(entities = [SleepNight::class], version = 1,  exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {
  1. Declare an abstract value that returns the SleepDatabaseDao:
 abstract val sleepDatabaseDao: SleepDatabaseDao
  1. Below, define a companion object:
 companion object {}
  1. Inside the companion object, declare a private nullable variable INSTANCE for the database.

    Initialize it to null, and annotate INSTANCE with @Volatile:

 @Volatile
 private var INSTANCE: SleepDatabase? = null
   
  1. Below, still inside the companion object, define the getInstance()method with a Context parameter, which will return a reference to the SleepDatabase:
 fun getInstance(context: Context): SleepDatabase {}
  1. Inside getInstance() add a synchronized{} block, and pass in this:
 synchronized(this) {}
  1. Inside the synchronized block, copy the current value of INSTANCE to a local variable, instance:
 var instance = INSTANCE
  1. At the end of the synchronized block, still inside the block, return instance:
  return instance
  1. Above the return statement, check if there is already a database stored in instance.

    If instance is null, use the database builder to get a database:

if (instance == null) {}
  1. Invoke Room’s databaseBuilder and supply the context that we passed in, the database class, and a name for the database:
instance = Room.databaseBuilder(
              context.applicationContext,
              SleepDatabase::class.java,
              "sleep_history_database"
              )
  1. Add the required migration strategy to the builder:
.fallbackToDestructiveMigration()
  1. And call .build():
.build()
  1. Assign INSTANCE = instance as the final step inside the if statement:
INSTANCE = instance
  1. Your final code should look like this:
@Database(entities = [SleepNight::class], version = 1, exportSchema = false)
abstract class SleepDatabase : RoomDatabase() {

   abstract val sleepDatabaseDao: SleepDatabaseDao

   companion object {

       @Volatile
       private var INSTANCE: SleepDatabase? = null

       fun getInstance(context: Context): SleepDatabase {
           synchronized(this) {
               var instance = INSTANCE

               if (instance == null) {
                   instance = Room.databaseBuilder(
                           context.applicationContext,
                           SleepDatabase::class.java,
                           "sleep_history_database"
                   )
                           .fallbackToDestructiveMigration()
                           .build()
                   INSTANCE = instance
               }
               return instance
           }
        }
     }
}
  1. Build and run your code to make sure there are no basic errors.

If you want to start at this step, you can download this exercise from: Step.03-Exercise-Create-RoomDatabase.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here: Step.03-Solution-Create-RoomDatabase, or using this git diff.

Task Description:

Complete these tasks to create the Room database.

Task List:

Task Feedback:

Great, you've just completed a key part of your app!